<template>
    <div class="side-menu">
        <div class="time-selection-wrapper" v-if="type === '1d'">
            <div class="time-selection">
                <table>
                    <thead>
                        <tr class="header">
                            <th>开始时间</th>
                            <th>结束时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(entry, index) in timeDay" :key="index">
                            <td>
                                <select
                                    v-model="entry.startTime"
                                    class="time"
                                    @change="validateStartDayPlan(entry)"
                                >
                                    <option disabled value="">请选择时间</option>
                                    <option v-for="time in timeOptions" :key="time" :value="time">
                                        {{ time }}
                                    </option>
                                </select>
                            </td>
                            <td>
                                <select
                                    v-model="entry.endTime"
                                    class="time"
                                    @change="validateEndDayPlan(entry)"
                                >
                                    <option disabled value="">请选择时间</option>
                                    <option v-for="time in timeOptions" :key="time" :value="time">
                                        {{ time }}
                                    </option>
                                </select>
                            </td>
                            <td>
                                <button
                                    :class="{ 'disabled-button': timeDay.length === 1 }"
                                    :disabled="timeDay.length === 1"
                                    @click.stop.prevent="removeDayPlan(index)"
                                >
                                    删除
                                </button>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <div class="button-wrapper">
                    <button @click="addDaycount" class="add-row-button">
                        <span class="plus-icon">+</span>
                        <span>新增一行</span>
                    </button>
                </div>
            </div>
        </div>
        <div class="time-selection-wrapper" v-if="type === '7d'">
            <div class="time-selection">
                <table>
                    <thead>
                        <tr class="header">
                            <th>开始时间</th>
                            <th>结束时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(entry, index) in timeWeekPlan" :key="index">
                            <td>
                                <div class="select-group">
                                    <select
                                        v-model="entry.startDay"
                                        class="week-selection"
                                        @change="validateEndWeekPlanStart(entry)"
                                    >
                                        <option disabled value="">请选择</option>
                                        <option
                                            v-for="day in weekDays"
                                            :key="day.value"
                                            :value="day.value"
                                        >
                                            {{ day.label }}
                                        </option>
                                    </select>
                                    <select
                                        v-model="entry.startTime"
                                        class="time"
                                        @change="validateEndWeekStartTime(entry)"
                                    >
                                        <option disabled value="">请选择时间</option>
                                        <option
                                            v-for="time in timeOptions"
                                            :key="time"
                                            :value="time"
                                        >
                                            {{ time }}
                                        </option>
                                    </select>
                                </div>
                            </td>
                            <td>
                                <div class="select-group">
                                    <select
                                        v-model="entry.endDay"
                                        class="week-selection"
                                        @change="validateEndWeekPlan(entry)"
                                    >
                                        <option disabled value="">请选择</option>
                                        <option
                                            v-for="day in weekDays"
                                            :key="day.value"
                                            :value="day.value"
                                        >
                                            {{ day.label }}
                                        </option>
                                    </select>
                                    <select
                                        v-model="entry.endTime"
                                        class="time"
                                        @change="validateEndTimeWeekPlan(entry)"
                                    >
                                        <option disabled value="">请选择时间</option>
                                        <option
                                            v-for="time in timeOptions"
                                            :key="time"
                                            :value="time"
                                        >
                                            {{ time }}
                                        </option>
                                    </select>
                                </div>
                            </td>
                            <td>
                                <button
                                    :class="{ 'disabled-button': timeWeekPlan.length === 1 }"
                                    :disabled="timeWeekPlan.length === 1"
                                    @click.stop="removeWeekPlan(index)"
                                >
                                    删除
                                </button>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <div class="button-wrapper">
                    <button @click="addWeekPlan" class="add-row-button">
                        <span class="plus-icon">+</span>
                        <span>新增一行</span>
                    </button>
                </div>
            </div>
        </div>
        <div class="time-selection-wrapper" v-if="type === '1m'">
            <div class="time-selection">
                <table>
                    <thead>
                        <tr class="header">
                            <th>开始时间</th>
                            <th>结束时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(entry, index) in timeMonthPlan" :key="index">
                            <td>
                                <div class="select-group">
                                    <select
                                        v-model="entry.startDay"
                                        class="week-selection"
                                        @change="validateEndMonthPlanStart(entry)"
                                    >
                                        <option disabled value="">请选择</option>
                                        <option v-for="day in monthDays" :key="day" :value="day">
                                            {{ day }}号
                                        </option>
                                    </select>
                                    <select
                                        v-model="entry.startTime"
                                        class="time"
                                        @change="validateMonthStartTime(entry)"
                                    >
                                        <option disabled value="">请选择时间</option>
                                        <option
                                            v-for="time in timeOptions"
                                            :key="time"
                                            :value="time"
                                        >
                                            {{ time }}
                                        </option>
                                    </select>
                                </div>
                            </td>
                            <td>
                                <div class="select-group">
                                    <select
                                        v-model="entry.endDay"
                                        class="week-selection"
                                        @change="validateEndMonthPlan(entry)"
                                    >
                                        <option disabled value="">请选择</option>
                                        <option v-for="day in monthDays" :key="day" :value="day">
                                            {{ day }}号
                                        </option>
                                    </select>
                                    <select
                                        v-model="entry.endTime"
                                        class="time"
                                        @change="validateEndTimeMonthPlan(entry)"
                                    >
                                        <option disabled value="">请选择时间</option>
                                        <option
                                            v-for="time in timeOptions"
                                            :key="time"
                                            :value="time"
                                        >
                                            {{ time }}
                                        </option>
                                    </select>
                                </div>
                            </td>
                            <td>
                                <button
                                    :class="{ 'disabled-button': timeMonthPlan.length === 1 }"
                                    :disabled="timeMonthPlan.length === 1"
                                    @click.stop="removeMonthPlan(index)"
                                >
                                    删除
                                </button>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <div class="button-wrapper">
                    <button @click="addMonthPlan" class="add-row-button">
                        <span class="plus-icon">+</span>
                        <span>新增一行</span>
                    </button>
                </div>
            </div>
        </div>
        <div class="visualization-wrapper">
            <date-plan
                :type="props.type"
                :timePlan="formattedTimePlans"
                @timeBackFill="handleTimeSelect"
                :isViewMonthPlan="true"
            />
        </div>
    </div>
</template>

<script lang="ts" setup>
import { computed, defineExpose, defineProps, nextTick, watch } from 'vue-demi';

import { ref } from '@vue/composition-api';
import dayjs from 'dayjs';

import DatePlan from './index.vue';

const props = defineProps<{
    type: string;
    default?: Array<{ [key: string]: string }>;
}>();

const emit = defineEmits([
    'update:timeDay',
    'update:timeWeekPlan',
    'update:timeMonthPlan',
    'layoutChange',
]);

const timeOptions = computed(() => {
    const options: string[] = [];
    for (let hour = 0; hour < 24; hour++) {
        for (let minute = 0; minute < 60; minute += 15) {
            const formattedTime = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
            options.push(formattedTime);
        }
    }
    options.push('23:59');
    return options;
});

//日计划
const validateEndDayPlan = (entry: TimeDay) => {
    if (entry.startTime && entry.endTime) {
        const [startHour, startMinute] = entry.startTime.split(':').map(Number);
        const [endHour, endMinute] = entry.endTime.split(':').map(Number);

        const startTotalMinutes = startHour * 60 + startMinute;
        const endTotalMinutes = endHour * 60 + endMinute;

        if (endTotalMinutes <= startTotalMinutes) {
            entry.endTime = '';
            alert('结束时间必须大于开始时间');
        }
        if (startTotalMinutes >= endTotalMinutes) {
            entry.startTime = '';
            alert('开始时间必须小于结束时间');
        }
    }
};
const validateStartDayPlan = (entry: TimeDay) => {
    if (entry.startTime && entry.endTime) {
        const [startHour, startMinute] = entry.startTime.split(':').map(Number);
        const [endHour, endMinute] = entry.endTime.split(':').map(Number);

        const startTotalMinutes = startHour * 60 + startMinute;
        const endTotalMinutes = endHour * 60 + endMinute;

        if (startTotalMinutes >= endTotalMinutes) {
            entry.startTime = '';
            alert('开始时间必须小于结束时间');
        }
    }
};

interface TimeDay {
    startTime: string;
    endTime: string;
}
const timeDay = ref<TimeDay[]>([
    {
        startTime: '',
        endTime: '',
    },
]);

const addDaycount = () => {
    timeDay.value.push({
        startTime: '',
        endTime: '',
    });

    // 使用 nextTick 确保 DOM 已更新
    nextTick(() => {
        // 触发布局变化事件
        emit('layoutChange');
    });
};

const removeDayPlan = (index: number) => {
    // 确保删除后至少还有一条数据
    if (timeDay.value.length > 1) {
        // 移除指定索引的时间块
        timeDay.value.splice(index, 1);

        // 使用 emit 通知父组件更新数据
        emit('update:timeDay', timeDay.value);

        // 使用 nextTick 确保 DOM 已更新
        nextTick(() => {
            // 触发布局变化事件
            emit('layoutChange');
        });
    }
};

interface DayPlan {
    startTime: string;
    endTime: string;
}

interface WeekOrMonthPlan {
    startDay: string;
    startTime: string;
    endDay: string;
    endTime: string;
}

const handleTimeSelect = (timePlans: Array<DayPlan | WeekOrMonthPlan>) => {
    if (props.type === '1d' && Array.isArray(timePlans)) {
        // 更新所有时间选择
        timeDay.value = (timePlans as DayPlan[]).filter((item) => item.startTime !== '');
    }
    if (props.type === '7d' && Array.isArray(timePlans)) {
        // 更新周计划
        timeWeekPlan.value = (timePlans as WeekOrMonthPlan[]).filter(
            (item) => item.startDay !== '' && item.startTime !== '',
        );
    }
    if (props.type === '1m' && Array.isArray(timePlans)) {
        // 更新月计划
        timeMonthPlan.value = (timePlans as WeekOrMonthPlan[]).filter(
            (item) => item.startDay !== '' && item.startTime !== '',
        );
    }
};

//周计划
interface TimeWeekPlan {
    startDay: string;
    startTime: string;
    endDay: string;
    endTime: string;
}
const timeWeekPlan = ref<TimeWeekPlan[]>([
    {
        startDay: '',
        startTime: '',
        endDay: '',
        endTime: '',
    },
]);

const addWeekPlan = () => {
    timeWeekPlan.value.push({
        startDay: '',
        startTime: '',
        endDay: '',
        endTime: '',
    });

    nextTick(() => {
        emit('layoutChange');
    });
};
const weekDays = [
    { label: '周一', value: '1' },
    { label: '周二', value: '2' },
    { label: '周三', value: '3' },
    { label: '周四', value: '4' },
    { label: '周五', value: '5' },
    { label: '周六', value: '6' },
    { label: '周日', value: '7' },
];
const removeWeekPlan = (index: number) => {
    if (timeWeekPlan.value.length > 1) {
        timeWeekPlan.value.splice(index, 1);
        emit('update:timeWeekPlan', timeWeekPlan.value);

        nextTick(() => {
            emit('layoutChange');
        });
    }
};

const validateEndWeekPlan = (entry: TimeWeekPlan) => {
    if (entry.startDay && entry.endDay) {
        const endDay = entry.endDay;
        const startDay = entry.startDay;
        if (endDay < startDay) {
            entry.endDay = '';
            alert('结束日期必须大于开始日期');
        }
    }
};
const validateEndWeekPlanStart = (entry: TimeWeekPlan) => {
    if (entry.startDay && entry.endDay) {
        const endDay = entry.endDay;
        const startDay = entry.startDay;

        if (startDay > endDay) {
            entry.startDay = '';
            alert('开始日期必须小于结束日期');
        }
    }
};
//判断时间的end>start
const validateEndTimeWeekPlan = (entry: TimeWeekPlan) => {
    if (entry.endDay === entry.startDay && entry.startTime && entry.endTime) {
        const [startHour, startMinute] = entry.startTime.split(':').map(Number);
        const [endHour, endMinute] = entry.endTime.split(':').map(Number);

        const startTotalMinutes = startHour * 60 + startMinute;
        const endTotalMinutes = endHour * 60 + endMinute;

        // 如果结束时间小于或等于开始时间，清空结束时间并给出提示
        if (endTotalMinutes <= startTotalMinutes) {
            entry.endTime = '';
            alert('结束时间必须大于开始时间');
        }
    }
};
const validateEndWeekStartTime = (entry: TimeWeekPlan) => {
    if (entry.endDay === entry.startDay && entry.startTime && entry.endTime) {
        const [startHour, startMinute] = entry.startTime.split(':').map(Number);
        const [endHour, endMinute] = entry.endTime.split(':').map(Number);

        const startTotalMinutes = startHour * 60 + startMinute;
        const endTotalMinutes = endHour * 60 + endMinute;

        // 如果结束时间小于或等于开始时间，清空结束时间并给出提示
        if (startTotalMinutes >= endTotalMinutes) {
            entry.startTime = '';
            alert('开始时间必须小于结束时间');
        }
    }
};

//月计划
interface TimeMonthPlan {
    startDay: string;
    startTime: string;
    endDay: string;
    endTime: string;
}
const timeMonthPlan = ref<TimeMonthPlan[]>([
    {
        startDay: '',
        startTime: '',
        endDay: '',
        endTime: '',
    },
]);

const addMonthPlan = () => {
    timeMonthPlan.value.push({
        startDay: '',
        startTime: '',
        endDay: '',
        endTime: '',
    });

    nextTick(() => {
        emit('layoutChange');
    });
};

const removeMonthPlan = (index: number) => {
    if (timeMonthPlan.value.length > 1) {
        timeMonthPlan.value.splice(index, 1);
        emit('update:timeMonthPlan', timeMonthPlan.value);

        nextTick(() => {
            emit('layoutChange');
        });
    }
};

function getDaysInMonth(year: number, month: number) {
    let date = dayjs(`${year}-${month}-01`);
    let lastDay = date.endOf('month');
    return lastDay.date();
}
// 2.调用函数
const currentDate = new Date();
let year = currentDate.getFullYear();
let month = currentDate.getMonth() + 1;
let days = getDaysInMonth(year, month);
const monthDays: number[] = Array.from({ length: days }, (_, i) => i + 1);
const startDayIndex = (day: number): number => {
    return monthDays.findIndex((item) => item === day); // 几号的索引
};
const validateEndMonthPlan = (entry: TimeMonthPlan) => {
    if (entry.startDay && entry.endDay) {
        const endDay = startDayIndex(Number(entry.endDay));
        const startDay = startDayIndex(Number(entry.startDay));

        if (endDay < startDay) {
            entry.endDay = '';
            alert('结束日期必须大于开始日期');
        }
    }
};
const validateEndMonthPlanStart = (entry: TimeMonthPlan) => {
    if (entry.startDay && entry.endDay) {
        const endDay = startDayIndex(Number(entry.endDay));
        const startDay = startDayIndex(Number(entry.startDay));

        if (startDay > endDay) {
            entry.startDay = '';
            alert('开始日期必须小于结束日期');
        }
    }
};
//判断时间的end>start
const validateEndTimeMonthPlan = (entry: TimeMonthPlan) => {
    if (entry.endDay === entry.startDay && entry.startTime && entry.endTime) {
        const [startHour, startMinute] = entry.startTime.split(':').map(Number);
        const [endHour, endMinute] = entry.endTime.split(':').map(Number);

        const startTotalMinutes = startHour * 60 + startMinute;
        const endTotalMinutes = endHour * 60 + endMinute;

        if (endTotalMinutes <= startTotalMinutes) {
            entry.endTime = '';
            alert('结束时间必须大于开始时间');
        }
    }
};
const validateMonthStartTime = (entry: TimeMonthPlan) => {
    if (entry.endDay === entry.startDay && entry.startTime && entry.endTime) {
        const [startHour, startMinute] = entry.startTime.split(':').map(Number);
        const [endHour, endMinute] = entry.endTime.split(':').map(Number);

        const startTotalMinutes = startHour * 60 + startMinute;
        const endTotalMinutes = endHour * 60 + endMinute;

        if (startTotalMinutes > endTotalMinutes) {
            entry.startTime = '';
            alert('开始时间必须小于结束时间');
        }
    }
};

// 统一时间格式
interface TimePlan {
    startDate: string;
    endDate?: string;
}

const getData = (type?: string) => {
    const unifiedTimePlans: TimePlan[] = [];

    const processPlans = (plans: any[], isWeeklyOrMonthly: boolean) => {
        return plans
            .map((entry) => {
                // 在这里检查 startTime 和 endTime 的存在性
                const hasStartTime = entry.startTime !== undefined;
                const hasEndTime = entry.endTime !== undefined;

                if (
                    (isWeeklyOrMonthly && entry.startDay && hasStartTime && entry.endDay) ||
                    hasEndTime ||
                    true || // 允许 endTime 不存在
                    (!isWeeklyOrMonthly && hasStartTime && (hasEndTime || true)) // 允许 endTime 不存在
                ) {
                    return isWeeklyOrMonthly
                        ? {
                              startDate: `${entry.startDay}-${entry.startTime}`,
                              endDate: hasEndTime ? `${entry.endDay}-${entry.endTime}` : undefined, // 允许 endDate 为 undefined
                          }
                        : {
                              startDate: entry.startTime,
                              endDate: hasEndTime ? entry.endTime : undefined, // 允许 endDate 为 undefined
                          };
                }
                return null;
            })
            .filter((item): item is TimePlan => item !== null);
    };

    const allPlans = [
        { plans: timeDay.value, isWeeklyOrMonthly: false }, // 日
        { plans: timeWeekPlan.value, isWeeklyOrMonthly: true }, // 周
        { plans: timeMonthPlan.value, isWeeklyOrMonthly: true },
    ];

    if (!type) {
        allPlans.forEach(({ plans, isWeeklyOrMonthly }) => {
            if (Array.isArray(plans) && plans.length > 0) {
                unifiedTimePlans.push(...processPlans(plans, isWeeklyOrMonthly));
            }
        });
    } else {
        if (type === '1d' && Array.isArray(timeDay.value) && timeDay.value.length > 0) {
            unifiedTimePlans.push(...processPlans(timeDay.value, false));
        } else if (
            type === '7d' &&
            Array.isArray(timeWeekPlan.value) &&
            timeWeekPlan.value.length > 0
        ) {
            unifiedTimePlans.push(...processPlans(timeWeekPlan.value, true));
        } else if (
            type === '1m' &&
            Array.isArray(timeMonthPlan.value) &&
            timeMonthPlan.value.length > 0
        ) {
            unifiedTimePlans.push(...processPlans(timeMonthPlan.value, true));
        }
    }

    return unifiedTimePlans;
};

defineExpose({
    getData,
});

watch(
    () => props.default,
    (newDefault) => {
        if (newDefault) {
            if (props.type === '1d') {
                timeDay.value = newDefault.map((entry) => ({
                    startTime: entry.startDate || '',
                    endTime: entry.endDate || '',
                }));
            } else if (props.type === '7d') {
                timeWeekPlan.value = newDefault.map((entry) => ({
                    startDay: entry.startDate.split('-')[0] || '',
                    startTime: entry.startDate.split('-').slice(1).join(':') || '',
                    endDay: entry.endDate.split('-')[0] || '',
                    endTime: entry.endDate.split('-').slice(1).join(':') || '',
                }));
            } else if (props.type === '1m') {
                timeMonthPlan.value = newDefault.map((entry) => ({
                    startDay: entry.startDate.split('-')[0] || '',
                    startTime: entry.startDate.split('-').slice(1).join(':') || '',
                    endDay: entry.endDate.split('-')[0] || '',
                    endTime: entry.endDate.split('-').slice(1).join(':') || '',
                }));
            }
        }
    },
    { immediate: true },
);
const formattedTimePlans = computed(() => getData(props.type));
console.log(formattedTimePlans);
</script>

<style lang="less" scoped>
@border-color: #cccccc;
@primary-color: #0075ff;
@text-color: #626567;
@header-color: #1b2833;
@hover-color: #353638;
@disabled-color: #999;
@background-color: #fff;

.side-menu {
    width: inherit;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.time-selection-wrapper {
    padding: 0 16px;
}

.time-selection {
    display: flex;
    flex-direction: column;
    width: 100%;
    border: 1px solid @border-color;
    border-radius: 8px;
    background-color: @background-color;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
    overflow: hidden;
}

.time-echarts {
    display: flex;
    justify-content: center;
    align-items: center;
}

.time,
.week-selection {
    appearance: none;
    background-color: @background-color;
    border: 1px solid @border-color;
    border-radius: 4px;
    padding: 0 8px;
    font-size: 13px;
    color: @text-color;
    transition: all 0.3s ease;
    height: 32px;

    &:hover {
        border-color: lighten(@primary-color, 20%);
    }

    &:focus {
        border-color: @primary-color;
        outline: none;
        box-shadow: 0 0 0 2px rgba(0, 117, 255, 0.1);
    }
}

.time {
    width: 100%;
}
.week-selection {
    width: 100%;
}
.curtain {
    height: 25px;
    margin: 10px;
}
.row {
    width: 250px;
    display: flex;
    margin: 10px;
}

.col {
    flex: 1;
    margin-right: 10px;
}

.col:last-child {
    margin-right: 0;
}

table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    word-break: break-all;
    overflow: hidden;

    // Remove border from last row
    tr:last-child td {
        border-bottom: none;
    }
}

td {
    border: 1px solid @border-color;
    text-align: center;
    width: auto;
    height: 28px;
    box-sizing: border-box;
    position: relative;
    padding: 8px;

    .select-group {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
    }
}

th {
    background-color: #f5f7fa;
    border: 1px solid @border-color;
    text-align: center;
    width: 20px;
    height: 28px;
    line-height: 28px;
    box-sizing: border-box;
    font-weight: 500;
    color: @header-color;
    padding: 8px;
}

.button-wrapper {
    padding: 16px;
    border-top: 1px solid @border-color;
    background-color: #f9fafb;
}

.add-row-button {
    width: 100%;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: @background-color;
    border: 1px dashed @border-color;
    color: @text-color;
    font-weight: normal;
    border-radius: 4px;
    transition: all 0.3s ease;
    cursor: pointer;
    margin: 0;

    .plus-icon {
        font-size: 16px;
        font-weight: bold;
        color: @primary-color;
    }

    &:hover {
        border-color: @primary-color;
        color: @primary-color;
        background-color: rgba(0, 117, 255, 0.02);
    }
}

button {
    margin: 0 8px;
    color: @primary-color;
    background-color: transparent;
    border: none;
    padding: 4px 8px;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s ease;

    &:hover {
        background-color: rgba(0, 117, 255, 0.1);
    }
}
.disabled-button {
    color: @disabled-color;
    cursor: not-allowed;

    &:hover {
        background-color: transparent;
    }
}
.no-focus:focus {
    outline: none;
    box-shadow: none;
    border: none;
}
.header {
    color: @header-color;
}

.visualization-wrapper {
    padding: 0 16px;
}
</style>
